package com.banyiyi.simple.pattern.function;

import java.util.*;
import java.util.function.*;
import java.util.stream.Collectors;

/**
 * @ClassName UtilFunction
 * @Description java.util.function 相关方法接口
 * @Author yangwm
 * @Date 2023/2/15 15:23
 * @Version 1.0
 */
public class UtilFunction {
    /**
     * Consumer（消费型），Supplier（供给型）、Predicate（判断型）与Function（转换型）
     */

    interface MathOperation {
        int operation(int a, int b);
        //int operation1(int a, int b);
    }
    static final int n =10;
    public static void main(String[] args) {
        // 方法实现方式
        MathOperation op = new MathOperation() {
            @Override
            public int operation(int a, int b) {
                return a+b;
            }
        };
        // 特点分析：仅有一个方法
        MathOperation op2 = (a,b) -> a+b;

        // 构造参数
        List<Integer> list = Arrays.asList(new Integer[]{1,2,3,4,5,6,7,8,9});

        // map reduce
        double bill = list.stream().map((cost) -> cost + 10*cost).reduce((sum, cost) -> sum + cost).get();
        System.out.println("Total : " + bill);

        // min max summaryStatistics
        List<Student> students = new ArrayList<Student>();
        students.add(Student.builder().name("张三").stuNo(2210).brithday("20020202").build());
        students.add(Student.builder().name("李四").stuNo(2209).brithday("20000119").build());

        Student st = students.stream().max(Comparator.comparing(Student::getStuNo)).get();
        System.out.println("学号较大的同学是:"+st.getName());

        IntSummaryStatistics stats = list.stream().mapToInt(x -> x).summaryStatistics();
        // 最大 最小 求和 平均值
        System.out.println("最大 : " + stats.getMax());
        System.out.println("最小 : " + stats.getMin());
        System.out.println("求和 : " + stats.getSum());
        System.out.println("平均值 : " + stats.getAverage());

        System.out.println("使用peek打印");

        List<Integer> collect = list.stream().map(x -> x + 10).parallel().peek(System.out::println).collect(Collectors.toList());

        Optional<Integer> any = list.stream().findAny();
        Integer integer = any.get();
        boolean b = any.isPresent();
        Integer integer1 = any.orElse(0);
        Supplier<? extends Integer> supplier1 =()-> 100;
        any.orElseGet(supplier1);


        for (int i = 0; i < 10; i++) {
            System.out.println(i);
        }

        // 使用Java 8的方法引用更方便，方法引用由::双冒号操作符标示，
        list.stream().forEach(i -> System.out.println(i));

        list.stream().map(i -> i + n);


        // 消费型
        //Consumer<Integer> consumer= i->System.out.println(i);
        Consumer<Integer> consumer= System.out::println;
        list.stream().forEach(consumer);
        //list.stream().forEach(i -> System.out.println(i));

        // 供给型
        Optional<Double> option = Optional.empty();
        //Optional.ofNullable(zoo).map(o -> o.getDog()).map(d->d.getAge()).filter(v->v==1).orElse(3);
        //Supplier<Integer> supplier =()-> 1;
        Supplier<Double> supplier =Math::random;
        boolean present = option.isPresent();
        Double aDouble = option.orElse(supplier.get());
        //System.out.println(aDouble);

        //判断型
        Predicate<Integer> predicate = i -> i > 6;
        //list.stream().filter(predicate).forEach(System.out::println);

        //函数型
        Function<Student,String> function =Student::getName;
        //students.stream().map(function).forEach(System.out::println);

        // 计算
        NumberCompuated<Student,Integer> compuated = (student)->{
            int year = Calendar.getInstance().get(Calendar.YEAR);
            Integer sub = Integer.valueOf(student.getBrithday().substring(0, 4));
            int age = year - sub;
            student.setAge(age);
            return age;
        };
        students.stream().forEach(t->System.out.println(compuated.calculate(t)));
        System.out.println("------------------------------");
        students.stream().map(Student::getAge).forEach(System.out::println);
        System.out.println("------------------------------");
        students.stream().forEach(System.out::println);
        System.out.println("++++++++++++++++++++++++++++++");
        NumberCompuated.state();
        compuated.say();


    }
}
